﻿#include"list.h"

//创建链表节点
ListNode* ListNewnode(LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		printf("malloc fail!\n");
		exit(-1);
	}
	newnode->_data = x;
	newnode->_next = NULL;
	newnode->_prev = NULL;
	return newnode;
}

// 创建返回链表的头结点.
ListNode* ListCreate()
{
	ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
	if (temp == NULL)
	{
		printf("malloc fail!\n");
	}
	temp->_next = temp;
	temp->_prev = temp;
	return temp;
}

// 双向链表销毁
void ListDestroy(ListNode* pHead)
{
	ListNode* pcur = pHead->_next;
	while (pcur != pHead)
	{
		ListNode* next = pcur->_next;
		free(pcur);
		pcur = next;
	}
	pHead->_next = NULL;
	pHead->_prev = NULL;
}

// 双向链表打印
void ListPrint(ListNode* pHead)
{
	assert(pHead != NULL);
	if (pHead->_next == pHead)
	{
		printf("NULL\n");
	}
	else
	{
		ListNode* pcur = pHead->_next;
		while (pcur != pHead)
		{
			printf("%d ", pcur->_data);
			pcur = pcur->_next;
		}
	}
	printf("\n");
}

// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	assert(pHead != NULL);
	ListInsert(pHead, x);
}

// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	assert(pHead != NULL);
	assert(pHead->_next != pHead);
	ListErase(pHead->_prev);
}

// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead != NULL);
	ListInsert(pHead->_next, x);
}

// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	assert(pHead != NULL);
	assert(pHead->_next != pHead);
	ListErase(pHead->_next);
}

// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	ListNode* pcur = pHead->_next;
	while (pcur != pHead)
	{
		if (pcur->_data == x)
		{
			return pcur;
		}
		pcur = pcur->_next;
	}
	return NULL;
}

// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos != NULL);
	ListNode* newnode = ListNewnode(x);
	newnode->_next = pos;
	newnode->_prev = pos->_prev;
	pos->_prev = newnode;
	newnode->_prev->_next = newnode;
}

// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	assert(pos != NULL);
	pos->_prev->_next = pos->_next;
	pos->_next->_prev = pos->_prev;
	free(pos);
}